//using System;
//using System.Xml;
//using System.IO;
//using System.Reflection;
//using System.Collections;
//using System.Globalization;
//using System.Configuration;

//namespace NetFramework.DataAccess.Configuration
//{
//    public delegate void LoadXMLHandler(string xml);
//     <summary>
//     ConfigManager maintains the configuration data read from xml files.
//     Setups watchers to handle xml files' changes.
//     Supplies xml to the subscribed parties, which parse it and instantiate their objects.
//     </summary>
//    public class ConfigManager
//    {
//        private class ConfigEntry 
//        {
//            private Hashtable _xmlDocs = new Hashtable();
//            private string _directoryPath = "";
//            private string _fileMask = "";
//            private Hashtable _elementHandlers = new Hashtable();

//            public string DirectoryPath
//            {
//                get { return _directoryPath; }
//                set { _directoryPath = value; }
//            }
//            public string FileMask
//            {
//                get { return _fileMask; }
//                set { _fileMask = value; }
//            }
//            public Hashtable ElementHandlers			
//            {
//                get { return _elementHandlers; }
//                set { _elementHandlers = value; }
//            }
//            private static DateTime _configLastChanged = DateTime.Now;

//            public void ExecuteHandler(string rootElement, LoadXMLHandler xmlHandler) 
//            {
//                XmlNode xmlNode = null;

//                if(_xmlDocs.Count == 0) return;

//                XmlDocument mergedDoc = new XmlDocument();
//                xmlNode = mergedDoc.CreateElement("merged" + rootElement);
//                mergedDoc.AppendChild(xmlNode);

//                foreach(DictionaryEntry entry in _xmlDocs) 
//                {
//                    xmlNode = ((XmlDocument)entry.Value).SelectSingleNode("//" + rootElement);
//                    xmlNode = mergedDoc.ImportNode(xmlNode, true);
//                    mergedDoc.DocumentElement.AppendChild(xmlNode);
//                }

//                if(mergedDoc.ChildNodes[0].ChildNodes.Count > 0)
//                    xmlHandler(mergedDoc.OuterXml);
//            }

//            public void ExecuteHandlers() 
//            {
//                foreach(DictionaryEntry entry in _elementHandlers) 
//                {
//                    ExecuteHandler((string)entry.Key, (LoadXMLHandler)entry.Value);
//                }
//            }

//            public void LoadXmlDocumentFromFiles() 
//            {
//                string[] fileNames = Directory.GetFiles(_directoryPath, _fileMask);

//                if(fileNames.Length == 0) 
//                    throw new ConfigurationException("No config files found with mask " + _directoryPath + Path.DirectorySeparatorChar + _fileMask + ".");

//                foreach(string fileName in fileNames) 
//                {
//                    LoadXmlDocumentFromFile(fileName);
//                }
//            }

//            private void LoadXmlDocumentFromFile(string fileName) 
//            {
//                fileName = fileName.ToLower(CultureInfo.InvariantCulture);

//                XmlDocument doc = new XmlDocument();
//                XmlTextReader reader = new XmlTextReader(fileName);
//                reader.WhitespaceHandling = WhitespaceHandling.None;
//                doc.Load(reader);
//                reader.Close();
//                if(_xmlDocs.Contains(fileName))
//                    _xmlDocs[fileName] = doc;
//                else
//                    _xmlDocs.Add(fileName, doc);
//            }

//            public void SetupWatcher() 
//            {
//                FileSystemWatcher watcher = new FileSystemWatcher(DirectoryPath, FileMask);
//                watcher.NotifyFilter = NotifyFilters.LastWrite;
//                watcher.Changed += new FileSystemEventHandler(this.Config_Changed);
//                watcher.EnableRaisingEvents = true;
//                _watchers.Add(...
//            }

//            private void Config_Changed(object sender, FileSystemEventArgs e) 
//            {
///*
//                this is a hack to prevent the event from being double-raised
//                TimeSpan timeDif = DateTime.Now - _configLastChanged;
//                if(timeDif.Seconds > 2) 
//                {
//                    LoadDataSources(e.FullPath);
//                    _configLastChanged = DateTime.Now;
//                }
//*/
//                LoadXmlDocumentFromFile(e.FullPath);
//                LoadXmlDocumentFromFile(e.FullPath);
//                ExecuteHandlers();
//            }
//        }

//        private static Hashtable _configEntries = new Hashtable();

//        static ConfigManager() 
//        {

//        }

//        private ConfigManager() {}

//        public static void ProcessConfig(string rootElement, LoadXMLHandler xmlHandler) 
//        {
//            gets the calling assembly directory and name
//            duplication needed because of Assembly.GetCallingAssembly
//            string codeBase = Assembly.GetCallingAssembly().CodeBase;
//            string directoryPath = Path.GetDirectoryName(codeBase.Replace(@"file:///",""));
//            string fileMask = Path.GetFileName(codeBase).Replace(".DLL", ".dll.config");

//            ProcessConfig(directoryPath, fileMask, rootElement, xmlHandler);
//        }

//        public static void ProcessConfig(string directoryPath, string fileMask, 
//            string rootElement, LoadXMLHandler xmlHandler) 
//        {
//            if(directoryPath == null || directoryPath == string.Empty 
//                || fileMask == null || fileMask == string.Empty)
//            {
//                gets the calling assembly directory and name
//                duplication needed because of Assembly.GetCallingAssembly
//                string codeBase = Assembly.GetCallingAssembly().CodeBase;

//                if(directoryPath == null || directoryPath == string.Empty) 
//                {
//                    directoryPath = Path.GetDirectoryName(codeBase.Replace(@"file:///",""));
//                }

//                if(fileMask == null || fileMask == string.Empty)
//                {
//                    fileMask = Path.GetFileName(codeBase).Replace(".DLL", ".dll.config");
//                }
//            }

//            string fullPath = directoryPath + Path.DirectorySeparatorChar + fileMask;

//            try to get config path from app.config
//            string overrideFullPath = ConfigurationSettings.AppSettings[rootElement];
//            if(overrideFullPath != null) 
//            {
//                fullPath = overrideFullPath;
//                directoryPath = Path.GetDirectoryName(fullPath);
//                fileMask = Path.GetFileName(fullPath);
//            }

//            ConfigEntry configEntry = _configEntries[fullPath] as ConfigEntry;
//            if(configEntry == null) 
//            {
//                configEntry = new ConfigEntry();
//                _configEntries.Add(fullPath, configEntry);

//                configEntry.DirectoryPath = directoryPath;
//                configEntry.FileMask = fileMask;
//                configEntry.LoadXmlDocumentFromFiles();
//                configEntry.SetupWatcher();
//            }

//            if(!configEntry.ElementHandlers.Contains(rootElement))
//                configEntry.ElementHandlers.Add(rootElement, xmlHandler);

//            configEntry.ExecuteHandler(rootElement, xmlHandler);
//        }
//    }
//}
